/*
 * Copyright 2009, Borqs
 *
 * File: lapi.h
 *
 * Revision: 1.0 RC2
 *
 * Date: 2009/7/10
 *
 * Description:
 *     Define interfaces between LAPI Server and plugable shared libraries.
 *
 *     LAPI Server is common daemon service to handle GPS/A-GPS tasks, and for
 *     different chipset, tasks will be handled by different shared library,
 *     which need implement interfaces defined in this head file.
 */
#ifndef _LAPI_H_
#define _LAPI_H_

#ifdef __cplusplus
extern "C" {
#endif

/* Primitive typedef */
typedef unsigned int LAPI_UINT32;
typedef unsigned short LAPI_UINT16;
typedef unsigned char LAPI_UINT8;
typedef int LAPI_INT32;
typedef short LAPI_INT16;
typedef char LAPI_INT8;
typedef unsigned short LAPI_WCHAR;
typedef unsigned char LAPI_BOOL;
typedef unsigned long long LAPI_UINT64;
typedef float LAPI_FLOAT;
typedef double LAPI_DOUBLE;

/*
 * Implementation must put all self logs under this path
 */
#define LAPI_LOG_PATH "/local/log/location"

/*
 * LAPI log level
 */
typedef enum
{
    LAPI_LOG_DBG = 5,
    LAPI_LOG_INF = 4,
    LAPI_LOG_ERR = 2
} LAPI_LOG_LEV;

/*
 * This function will record logs to "lapi_log.txt", LAPI Server also write logs to it.
 *
 * Implementation can use it or save logs to self log file
 */
typedef void (* LAPI_LOG) (LAPI_LOG_LEV lev, const char *fmt, ...);

#define AGPS_SRV_ADDR_LEN (32+1)
#define AGPS_IMSI_LEN (15 + 1)
#define AGPS_LAC_LEN (4 + 1)
#define AGPS_CID_LEN (4 + 1)
#define AGPS_GPRSIF_LEN 8
#define AGPS_CA_PATH_LEN (32+1)
#define AGPS_NW_OP_LEN (6+1)
#define AGPS_NW_TYPE_LEN (16+1)
#define MAX_OTAMSG_LEN (256)
#define REQUESTERID_LEN (51)
#define CLIENTNAME_LEN (51)
#define MAX_SATELLITE (12)

/*
 * Location Method Types
 *
 * MSA/MSB is mandatory for CMCC
 * Autonomous is option
 * Standalone is GPS only
 *
 * Combo/ECID can be ignored now
 */
typedef enum
{
    /* Indicates that the SUPL Autonomous Location Method is to be used */
    LAPI_LOCATION_METHOD_AUTONOMOUS = 0,
        
    /* Indicates that the MS-Based (Network Assisted) Location Method is to be used 
    and Measure Position Request OTA */
    LAPI_LOCATION_METHOD_MS_BASED,
        
    /* Indicates that the MS-Assisted (Network Centric) Location Method is to be used */
    LAPI_LOCATION_METHOD_MS_ASSISTED,

    /* Indicates that a combination of methods is to be used. The final Location method 
     * will be determined by the handshaking between SET and SLC
     */
    LAPI_LOCATION_METHOD_COMBO,

    /* Indicates that the Standalone Location Method is to be used */
    LAPI_LOCATION_METHOD_STANDALONE,
    
    /* Indicates that the Enhanced Cell ID Location Method is to be used */
    LAPI_LOCATION_METHOD_ECID
} LAPI_LOCATION_METHOD;

/*
 * Reset Types
 *
 * OMS use COLD/HOT now
 */
typedef enum
{
    /* Indicates that Factory Reset command should be sent to the GPS Client at the start of a session */
    LAPI_RESET_TYPE_FACTORY_RESET = 0,
        
    /* Indicates a Cold Start Reset command should be sent to the GPS Client at the start of a session */
    LAPI_RESET_TYPE_COLD_RESET,
        
    /* Indicates a Hot Start Reset command should be sent to the GPS Client at the start of a session */
    LAPI_RESET_TYPE_HOT_RESET,

    /* Indicates a Warm Start Reset command should be sent to the GPS Client at the start of a session */
    LAPI_RESET_TYPE_WARM_RESET
} LAPI_RESET_TYPE;

/*
 * Assist Protocol
 *
 * User Plane
 * Control Plane
 */
typedef enum
{
    LAPI_ASSIST_PROTOCOL_USER_PLANE = 0,
    LAPI_ASSIST_PROTOCOL_CONTROL_PLANE
} LAPI_ASSIST_PROTOCOL;

/*
 * Config items for GPS/A-GPS settings, will be passed to implementation
 * when call LAPI_LIB_Init
 */
typedef struct _LAPI_SETTING_S {
    // Location Method
    LAPI_LOCATION_METHOD method;
    // Reset Type
    LAPI_RESET_TYPE reset;
    // A-GPS server address
    char srv_addr[AGPS_SRV_ADDR_LEN];
    // A-GPS server port
    LAPI_UINT32 srv_port;
    // Criteria of location fix, only meet this criteria should report
    struct {
        // Accuracy in hor, unit is meter
        LAPI_UINT32 hor_accuracy;
        // Accuracy in ver, unit is meter
        LAPI_UINT32 ver_accuracy;
        /*
         * If can't get location fix with given timeout, should report TIMEOUT
         * unit is second
         */
        LAPI_UINT32 timeout;
    } qos;
    // Interval between two location fix, unit is second
    LAPI_UINT32 interval;
    // Below configs are for A-GPS
    // IMSI of SIM card
    char imsi[AGPS_IMSI_LEN];
    // LAC
    char lac[AGPS_LAC_LEN];
    // Cell ID
    char cid[AGPS_CID_LEN];
    // GPRS device like: ccinet0, will be bind after create socket
    char gprs_dev[AGPS_GPRSIF_LEN];
    // APN id, can be ignored
    //LAPI_UINT32 gprs_pro;
    // Full path of CA file, such as: /system/location/AGPS_CA.pem
    char ca_path[AGPS_CA_PATH_LEN];
    // Assist protocol
    LAPI_ASSIST_PROTOCOL assist_pro;
    /*
     * Network operator info: MCC + MNC (5 or 6 digits), 
     * MNC in North America are 3 digits, out of North America are 2 digits
     *
     * For example:
     *   China Mobile 46000
     *   ATT 310150
     */
    char nw_op[AGPS_NW_OP_LEN];
    /*
     * Network type: GPRS/EDGE/TD_HSPA/UMTS_HSDPA etc.
     */
    char nw_type[AGPS_NW_TYPE_LEN];
} LAPI_SETTING_S;

/*
 * Session type, MO or MT
 */
typedef enum
{
    LAPI_MO_SESSION = 0,
    LAPI_MT_SESSION
} LAPI_SESSION_TYPE;

/*
 * User action of MTLR
 */
typedef enum
{
    LAPI_MTLR_ACCEPT = 0,
    LAPI_MTLR_REJECT,
    LAPI_MTLR_IGNORE
} LAPI_MTLR_USR_ACTION;

/* 
 * Satellite infomation
 */
typedef struct _SATELLITE_INFO_S {
    LAPI_UINT8   satelliteId;
    LAPI_UINT8   signalStrength;
    LAPI_UINT16  azimuth;
    LAPI_UINT8   elevationAngle;
} __attribute__((packed)) SATELLITE_INFO_S;


/*
 * Location fix
 */
typedef struct _LAPI_LOCATION_S {
    LAPI_DOUBLE longitude;
    LAPI_DOUBLE latitude;
    LAPI_FLOAT altitude;
    LAPI_UINT16 bearing; // degree, 0-360
    LAPI_UINT16 speed; // unit: km/h
    LAPI_UINT64 timeStamp; // unit: millisecond, from 1970/01/01 00:00:00
    LAPI_UINT16 ttff; // unit: second
    LAPI_UINT16 accuracy; // unit: meter
    LAPI_UINT16 num_satellite;
    SATELLITE_INFO_S satellite_info[MAX_SATELLITE];
} __attribute__((packed)) LAPI_LOCATION_S;

/*
 * MTLR OTA message structure
 */
typedef struct _LAPI_OTAMSG_S {
    LAPI_UINT32 length;
    LAPI_UINT8 data[MAX_OTAMSG_LEN];
} __attribute__((packed)) LAPI_OTAMSG_S;

/* 
 * MTLR user response type
 */
typedef struct _LAPI_MTLR_USR_RSP
{
    LAPI_UINT8 notification_present;
    LAPI_UINT8 encoding_type_present;
    LAPI_UINT8 requester_id_present;
    LAPI_UINT8 requester_id_type_present;
    LAPI_UINT8 client_name_present;
    LAPI_UINT8 client_name_type_present;
    LAPI_UINT8 notification_type;
    LAPI_UINT8 encoding_type;
    LAPI_UINT8 requesterID_type;
    LAPI_UINT8 clientName_type;
    LAPI_UINT8 requesterId_len;
    LAPI_UINT8 clientName_len;
    LAPI_UINT8 requesterId[REQUESTERID_LEN];
    LAPI_UINT8 clientName[CLIENTNAME_LEN];
} __attribute__((packed)) LAPI_MTLR_USR_RSP;

/*
 * Status of location update
 */
typedef enum
{
    LAPI_LOCATION_STATUS_VALID = 0,
    // can't meet criteria
    LAPI_LOCATION_STATUS_INVALID,
    // can'g get location within "timeout"
    LAPI_LOCATION_STATUS_TIMEOUT,
    LAPI_LOCATION_STATUS_UNKNOWN,
    // NI session end, can close network
    LAPI_LOCATION_STATUS_END_NORMAL,
    LAPI_LOCATION_STATUS_END_ABNORMAL,
} LAPI_LOCATION_STATUS;

/*
 * Location listener callback function prototype
 *
 * @param LAPI_LOCATION_S* - location fix, will be NULL if status != LAPI_LOCATION_STATUS_VALID
 * @param LAPI_LOCATION_STATUS - status of location update
 * @return void
 */
typedef void (*LAPI_LocationListener)(LAPI_LOCATION_S* fix, LAPI_LOCATION_STATUS status);

/*
 * NMEA listener callback function prototype
 *
 * @param LAPI_UINT8* - NMEA sentences
 * @param LAPI_UINT16 - length of NMEA sentences
 * @return void
 */
typedef void (*LAPI_NMEAListener)(LAPI_UINT8* message, LAPI_UINT16 length);

/*
 * SUPL_INIT listener callback function prototype
 *
 * @param LAPI_MTLR_USR_RSP* -  MTLR user response type
 * @return void
 */
typedef void (*LAPI_SUPLInitListener)(LAPI_MTLR_USR_RSP* rsp);

/*
 * LAPI_LIB init function, this function will be called by LAPI Server before others
 *
 * @param LAPI_SETTING_S* - settings, include location method, reset type, etc.
 * @param LAPI_SESSION_TYPE - MO or MT session
 * @param LAPI_OTAMSG_S* - OTA message, for MT session, will be NULL for MO session
 * @return LAPI_INT32 - 0 for success, others means error
 */
typedef LAPI_INT32 (*LAPI_LIB_Init) (LAPI_LOG log_handler, const LAPI_SETTING_S *cfg,
                                     LAPI_SESSION_TYPE type, LAPI_OTAMSG_S *msg);

/*
 * LAPI_LIB cleanup function, when no client connect, LAPI Server will call this function
 *
 * @param void
 * @return LAPI_INT32 - 0 for success, others means error
 */
typedef LAPI_INT32 (*LAPI_LIB_Exit) (void);

/*
 * LAPI_LIB start function, let chipset work, called after LAPI_LIB_Init.
 *
 * @return LAPI_INT32 - 0 for success, others means error
 */
typedef LAPI_INT32 (*LAPI_LIB_Start) (void);

/*
 * LAPI_LIB stop function, called before LAPI_LIB_Exit.
 *
 * @return LAPI_INT32 - 0 for success, others means error
 */
typedef LAPI_INT32 (*LAPI_LIB_Stop) (void);

/*
 * Add a location listener
 *
 * @param LAPI_LocationListener
 * @return LAPI_INT32 - 0 for success, others means error
 */
typedef LAPI_INT32 (*LAPI_LIB_AddLocationListener) (LAPI_LocationListener listener);

/*
 * Remove a location listener
 *
 * @param LAPI_LocationListener
 * @return LAPI_INT32 - 0 for success, others means error
 */
typedef LAPI_INT32 (*LAPI_LIB_RmLocationListener) (LAPI_LocationListener listener);

/*
 * Add a NMEA listener
 *
 * @param LAPI_NMEAListener
 * @return LAPI_INT32 - 0 for success, others means error
 */
typedef LAPI_INT32 (*LAPI_LIB_AddNMEAListener) (LAPI_NMEAListener listener);

/*
 * Remove a NMEA listener
 *
 * @param LAPI_NMEAListener
 * @return LAPI_INT32 - 0 for success, others means error
 */
typedef LAPI_INT32 (*LAPI_LIB_RmNMEAListener) (LAPI_NMEAListener listener);

/*
 * Add a SUPL_INIT listener, for MT session
 *
 * @param LAPI_SUPLInitListener
 * @return LAPI_INT32 - 0 for success, others means error
 */
typedef LAPI_INT32 (*LAPI_LIB_AddSUPLInitListener) (LAPI_SUPLInitListener listener);

/*
 * Remove a SUPL_INIT listener, for MT session
 *
 * @param LAPI_SUPLInitListener
 * @return LAPI_INT32 - 0 for success, others means error
 */
typedef LAPI_INT32 (*LAPI_LIB_RmSUPLInitListener) (LAPI_SUPLInitListener listener);

/*
 * Confirm MTLR with user action
 *
 * @param LAPI_MTLR_USR_ACTION
 * @return LAPI_INT32 - 0 for success, others means error
 */
typedef LAPI_INT32 (*LAPI_LIB_ConfirmMTLR) (LAPI_MTLR_USR_ACTION action);

/*
 * If user disable GPS/A-GPS in "Setting -> My Location", will notify implementation by
 * this function, implementation should power off chipset or enter sleep mode for power saving
 *
 * @return void
 */
typedef void (*LAPI_LIB_Disabled) (void);

/*
 * Data structure of LAPI_LIB callback functions
 *
 * If some callbakc can't be support, should set to "NULL"
 */
typedef struct
{
    LAPI_LIB_Init onInit;
    LAPI_LIB_Exit onExit;
    LAPI_LIB_Start onStart;
    LAPI_LIB_Stop onStop;
    LAPI_LIB_AddLocationListener onAddLocationListener;
    LAPI_LIB_RmLocationListener onRmLocationListener;
    LAPI_LIB_AddNMEAListener onAddNMEAListener;
    LAPI_LIB_RmNMEAListener onRmNMEAListener;
    LAPI_LIB_AddSUPLInitListener onAddSUPLInitListener;
    LAPI_LIB_RmSUPLInitListener onRmSUPLInitListener;
    LAPI_LIB_ConfirmMTLR onConfirmMTLR;
    LAPI_LIB_Disabled onDisabled;
} LAPI_LIB_Functions;

/*
 * LAPI_LIB implementations must define LAPI_LIB_Load,
 * it will return callbacks to LAPI Server
 *
 * @param void
 * @return *LAPI_LIB_Functions
 */
const LAPI_LIB_Functions *LAPI_LIB_Load(void);

#ifdef __cplusplus
}
#endif

#endif
